home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PROGRAMM
/
DB_CLIPP
/
2614.ZIP
/
DISPLA.ZIP
/
DISPLAY.C
< prev
next >
Wrap
Text File
|
1990-12-22
|
20KB
|
712 lines
/* display.c */
// this #define chooses whether or not Clipper 5.0 code is to be generated
#define CLIPPER5
#include "extend.h"
#include "display.h"
#include "keys.h"
/*
* d_chattr() replace the color attribute with a new one starting at
* location x, y and going for length len.
*
*/
void d_chattr(int x, int y, int len, int attr)
{
int i;
char far *vmem;
vmem = d_vseg;
FP_OFF(vmem) = (y * 160) + (x * 2) + 1; // calc the screen memory coord
for (i = 0; i < len; i++, vmem += 2) // write the new attribute value
*vmem = (char) attr;
}
/*
* d_keyin() gets the next key typed and does any translation needed.
* Some keys are converted to a common name - like the up arrow is
* converted to the UP value which also is the Ctrl-E value. This
* allows the Wordstar-like control keys to be used. Only extended
* keys are translated - the values of the defines were chosen to
* match up with the non-extended key codes.
*
*/
unsigned char d_keyin()
{
unsigned char ch;
ch = (unsigned char) d_getkey(); // get the next key
if ( ch == 0x00 ) // check to see if it's extended
{
ch = (unsigned char) d_getkey(); // if so, read the second part
switch ( ch ) // and convert it
{
case 75 : ch = LFT; break;
case 77 : ch = RGT; break;
case 72 : ch = UP; break;
case 80 : ch = DN; break;
case 71 : ch = HOME; break;
case 79 : ch = ENND; break;
case 73 : ch = PGUP; break;
case 81 : ch = PGDN; break;
case 62 : ch = F4; break;
case 117 : ch = CENND; break;
case 119 : ch = CHOME; break;
case 118 : ch = CPGDN; break;
case 132 : ch = CPGUP; break;
case 116 : ch = CRGT; break;
case 115 : ch = CLFT; break;
case 82 : ch = INS; break;
case 83 : ch = DEL; break;
case 68 : ch = F0; break;
case 59 : ch = F1; break;
case 60 : ch = F2; break;
case 61 : ch = F3; break;
case 63 : ch = F5; break;
case 64 : ch = F6; break;
case 65 : ch = F7; break;
case 66 : ch = F8; break;
case 67 : ch = F9; break;
case 113 : ch = AF0; break;
case 104 : ch = AF1; break;
case 105 : ch = AF2; break;
case 106 : ch = AF3; break;
case 107 : ch = AF4; break;
case 108 : ch = AF5; break;
case 109 : ch = AF6; break;
case 110 : ch = AF7; break;
case 111 : ch = AF8; break;
case 112 : ch = AF9; break;
case 94 : ch = CF1; break;
case 95 : ch = CF2; break;
case 96 : ch = CF3; break;
case 97 : ch = CF4; break;
case 98 : ch = CF5; break;
case 99 : ch = CF6; break;
case 100 : ch = CF7; break;
case 101 : ch = CF8; break;
case 102 : ch = CF9; break;
case 103 : ch = CF0; break;
case 120 : ch = ALT1; break;
case 121 : ch = ALT2; break;
case 122 : ch = ALT3; break;
case 123 : ch = ALT4; break;
case 124 : ch = ALT5; break;
case 125 : ch = ALT6; break;
case 126 : ch = ALT7; break;
case 127 : ch = ALT8; break;
case 128 : ch = ALT9; break;
case 129 : ch = ALT0; break;
case 130 : ch = ADASH; break;
case 131 : ch = AEQL; break;
case 30 : ch = ALTA; break;
case 48 : ch = ALTB; break;
case 46 : ch = ALTC; break;
case 32 : ch = ALTD; break;
case 18 : ch = ALTE; break;
case 33 : ch = ALTF; break;
case 34 : ch = ALTG; break;
case 35 : ch = ALTH; break;
case 23 : ch = ALTI; break;
case 36 : ch = ALTJ; break;
case 37 : ch = ALTK; break;
case 38 : ch = ALTL; break;
case 50 : ch = ALTM; break;
case 49 : ch = ALTN; break;
case 24 : ch = ALTO; break;
case 25 : ch = ALTP; break;
case 16 : ch = ALTQ; break;
case 19 : ch = ALTR; break;
case 31 : ch = ALTS; break;
case 20 : ch = ALTT; break;
case 22 : ch = ALTU; break;
case 47 : ch = ALTV; break;
case 17 : ch = ALTW; break;
case 45 : ch = ALTX; break;
case 21 : ch = ALTY; break;
case 44 : ch = ALTZ; break;
default : ch = 0; break;
}
}
return ( ch );
}
/*
* function d_getblock() reads the text file and returns the a block.
* the variables offset and buffsize tell it where to start reading and
* how many bytes to try to read. if the block read in would not fill
* the buffer then the offset is adjusted so that the start or end of
* of the file is positioned at the head or tail of the buffer.
*
* it returns the offset into the file of the first byte of the buffer.
*
*/
long d_getblock(long offset)
{
// set the file pointer to the proper offset
// and if an error occured then check to see
// if a positive offset was requested, if so
// then set the pointer to the offset from
// the end of the file, otherwise set it from
// the beginning of the file.
d_fileseek(d_infile, offset, SEEK_SET);
// read in the file and set the buffer bottom variable equal
// to the number of bytes actually read in.
d_buffbot = d_fileread(d_infile, d_buffer, d_buffsize);
// if a full buffer's worth was not read in, make it full.
if (( d_buffbot != d_buffsize ) && ( d_fsize > d_buffsize ))
{
if ( offset > 0 )
d_fileseek(d_infile, (long) -d_buffsize, SEEK_END);
else
d_fileseek(d_infile, (long) d_buffsize, SEEK_SET);
d_buffbot = d_fileread(d_infile, d_buffer, d_buffsize);
}
// return the actual file position */
return(d_filepos(d_infile) - d_buffbot);
}
/*
* d_buff_align makes sure the buffer top and bottom variables point
* to actual complete lines of text.
*
*/
void d_buff_align()
{
int i;
d_bufftop = 0;
d_buffbot = d_buffsize;
if ( d_buffoffset != 0L ) // if the d_buffoffset is otherthan 0
{
i = d_bufftop; // start at the top of the file and scan
// forward until a CR is reached.
while (( d_buffer[i] != CR ) && ( i < d_buffbot ))
i++;
d_bufftop = i + 2; // skip past the CR/LF to the first char
}
// if the buffer offset is not a complete */
// buffer's length away from the file end */
if ( d_buffoffset + ((long) d_buffbot) != d_fsize )
{
// if the file position of the last byte
// of the buffer would end up past the
// end of the file, then the buffer does
// contain a complete buffer full and the
// buffer end pointer needs to be set to
// the last character of the file.
if ( d_buffoffset + ((long) d_buffbot) > d_fsize )
d_buffbot = (int) (d_fsize - d_buffoffset);
i = d_buffbot; // point the end of the buffer to a valid
// complete text line.
while (( d_buffer[i] != CR ) && ( i > d_bufftop ))
i--;
d_buffbot = i + 2; // skip past the CR/LF to the first char */
}
}
/*
* d_win_align takes the value for d_wintop and then figures out where
* d_winbot would be. if d_winbot would extend past the end of the
* buffer, then the top of the window is adjusted to ensure that a full
* screen of text will appear. This simplifies the cursor routines.
*
*/
void d_win_align()
{
int i;
d_winbot = d_wintop; // find out if there is enough text for
i = 0; // full window.
while (( d_winbot < d_buffbot ) && ( i < d_height ))
{
if ( d_buffer[d_winbot] == CR )
i++;
d_winbot++;
}
if ( i < d_height ) // if there is not a full window,
{
while ( d_buffer[d_winbot] != LF ) // then retrofit d_winbot
d_winbot--; // to the end of a line
d_wintop = d_winbot;
i = 0; // and setup d_wintop
while (( d_wintop > d_bufftop ) && ( i <= d_height ))
{
if ( d_buffer[d_wintop] == LF )
i++;
d_wintop--;
}
if ( d_wintop != d_bufftop )
d_wintop += 2;
}
}
/*
* this routine displays the actual text in the window. This is done
* by taking each line and placing it in a string. the screen line
* is then taken from the appropriate group of characters in the string.
* this allows a window to page left-right across the buffer without
* having to use any complex algorithm to calc the needed chars.
*
*/
void d_disp_update(int offset)
{
int line, col, pos, i;
char far *vmem;
vmem = d_vseg;
d_refresh = NO;
line = 0;
while ( line < d_height )
{
// calculate the initial position, this save execution
// time because each column is considered as a offset
// from the line start
pos = ((d_sline + line) * 160) + (d_scol * 2);
// copy string to temp buffer
for (i = 0; d_buffer[offset] != CR && offset <= d_winbot; offset++)
{
if ( i < d_maxlin )
d_lbuff[i++] = d_buffer[offset];
}
for (; i < d_maxlin; i++) // fill out with spaces
d_lbuff[i] = ' ';
// place the proper characters onto the screen
for (i = d_wincol - 1, col = 0; col < d_wincol + d_width - 1; col++)
{
FP_OFF(vmem) = pos + (col * 2);
*vmem = d_lbuff[i++];
}
line += 1;
offset += 2;
}
}
void d_winup()
{
int k;
long i, j;
d_refresh = YES;
k = d_wintop - 3;
while (( d_buffer[k] != CR ) && ( k > d_bufftop ))
k--;
if ( k >= d_bufftop )
{
if ( d_buffer[k] == CR )
k += 2;
d_wintop = k;
k = d_winbot - 3;
while ( d_buffer[k] != CR )
k--;
d_winbot = k + 2;
}
else
if ( ((long) d_bufftop) + d_buffoffset > 0 && d_fsize > d_buffsize )
{
i = d_buffoffset + d_wintop;
j = d_buffoffset - ((long) (d_buffsize / 2));
if ( j < 0 )
j = 0;
d_buffoffset = d_getblock(j);
d_wintop = ((int) (i - d_buffoffset));
d_buff_align();
d_win_align();
}
}
void d_windown()
{
int k;
long i, j;
d_refresh = YES;
k = d_winbot;
while (( d_buffer[k] != CR ) && ( k <= d_buffbot ))
k++;
k += 2;
if ( k <= d_buffbot )
{
d_winbot = k;
k = d_wintop;
while ( d_buffer[k] != CR )
k++;
d_wintop = k + 2;
}
else
if ( (((long) d_buffbot) + d_buffoffset) < d_fsize && d_fsize > d_buffsize)
{
i = d_buffoffset + d_wintop;
j = i;
if ( j > d_fsize )
j = d_fsize - ((long) d_buffsize);
d_buffoffset = d_getblock(j);
if ( i < d_buffoffset )
d_wintop = 0;
else
d_wintop = ((int) (i - d_buffoffset));
d_buff_align();
d_win_align();
}
}
/* move the cursor one line down */
void d_linedown()
{
if ( d_winrow < d_eline ) // if cursor not at last line
d_winrow += 1;
else // otherwise adjust the window top variable
d_windown();
}
/* move the cursor one line up */
void d_lineup()
{
if ( d_winrow > d_sline )
d_winrow -= 1;
else
d_winup();
}
/* go to the top of the file */
void d_filetop()
{
if ( d_buffoffset != 0 )
{
d_buffoffset = d_getblock(0L);
d_buff_align();
}
d_refresh = YES;
d_wintop = (int) d_buffoffset;
d_winrow = d_sline;
d_wincol = 1;
d_win_align();
}
/* goto the bottom of the file */
void d_filebot()
{
if ( (((long) d_buffbot) + d_buffoffset) < d_fsize && d_fsize > d_buffsize )
{
d_buffoffset = d_getblock(d_fsize + 1);
d_buff_align();
}
d_refresh = YES;
d_wintop = d_buffbot - 3;
d_winrow = d_eline;
d_wincol = 1;
d_win_align();
}
CLIPPER dispfile()
{
int i, j, done, hlight, norm;
int mcount;
int colinc, brows;
char rval[2], fname[15];
char mstr[25];
unsigned char ch;
FP_SEG(d_vseg) = d_vconfig(); // get the video buffer segment address
strcpy(fname, _parc(1)); // retrieve the filename
if ( _parinfo(12) == 0 )
d_maxlin = MAXLINE;
else
d_maxlin = _parni(12);
d_infile = d_fileopen(fname, READONLY); // open the file as read-only
#ifdef CLIPPER5
if ( _parinfo(13) == 0 ) // buffer size passed?
d_buffsize = _parni(13);
else
d_buffsize = BUFFERSIZE;
d_buffer = _xalloc(d_buffsize);
d_lbuff = _xalloc(d_maxlin);
if (( d_buffer == NULL ) || ( d_lbuff == NULL ))
{
d_fileclose(d_infile);
d_infile = 0;
}
#else
d_buffsize = BUFFERSIZE;
if ( d_maxlin > MAXLINE ) // prevent rmargin larger than line buff size
d_maxlin = MAXLINE;
#endif
if ( d_infile == 0 ) // check for file open error
{
rval[0] = (char) 0; // build the return string char 0 tells
rval[1] = '\0'; // the calling routine that an error occured
}
else // if file opened okay, then get parameters
{
d_sline = _parni(2);
d_scol = _parni(3);
d_eline = _parni(4);
d_ecol = _parni(5);
j = _parni(6);
norm = _parni(7);
hlight = _parni(8);
strcpy(mstr, _parc(9));
brows = _parl(10);
if ( _parinfo(11) == 0 )
colinc = 1;
else
colinc = _parni(11);
d_width = d_ecol - d_scol + 1;
d_height = d_eline - d_sline + 1;
mcount = strlen(mstr);
d_bufftop = 0;
d_buffbot = d_buffsize;
d_buffoffset = 0;
d_winrow = d_sline;
d_wincol = 1;
d_wintop = 0;
d_winbot = 0;
d_fsize = d_fileseek(d_infile, 0L, SEEK_END) - 1;
// get the first block
d_fileseek(d_infile, 0L, SEEK_SET);
// if block less than d_buffsize
if ( d_fsize < ((long) d_buffbot) )
d_buffbot = (int) d_fsize; // then set buffer bottom
d_buffoffset = d_getblock((long) d_bufftop);
d_buff_align();
d_win_align();
// point line pointer to line passed by caller
for (i = 1; i < j; i++)
d_linedown();
done = NO;
d_refresh = YES;
for (i = d_sline; i <= d_eline; i++)
d_chattr(d_scol, i, d_width, norm);
do
{
if ( d_refresh == YES )
d_disp_update(d_wintop);
if ( brows == NO )
d_chattr(d_scol, d_winrow, d_width, hlight);
d_gotoxy(d_scol, d_winrow);
ch = d_keyin();
if ( brows == NO )
d_chattr(d_scol, d_winrow, d_width, norm);
switch (ch)
{
case DN : if ( brows == YES )
d_winrow = d_eline;
d_linedown();
break;
case UP : if ( brows == YES )
d_winrow = d_sline;
d_lineup();
break;
case LFT : d_wincol -= colinc;
d_refresh = YES;
if ( d_wincol < 1 )
d_wincol = 1;
break;
case RGT : d_wincol += colinc;
d_refresh = YES;
if ( d_wincol > (d_maxlin - d_width) )
d_wincol = d_maxlin - d_width;
break;
case HOME : d_wincol = 1;
d_refresh = YES;
break;
case ENND : d_wincol = d_maxlin - d_width;
d_refresh = YES;
break;
case CLFT : d_wincol -= 16;
d_refresh = YES;
if ( d_wincol < 1 )
d_wincol = 1;
break;
case CRGT : d_wincol += 16;
d_refresh = YES;
if ( d_wincol > (d_maxlin - d_width) )
d_wincol = d_maxlin - d_width;
break;
case PGUP : for (i = 0; i < d_height; i++)
d_winup();
break;
case PGDN : for (i = 0; i < d_height; i++)
d_windown();
break;
case CPGUP : d_filetop();
break;
case CPGDN : d_filebot();
break;
case RET : done = YES;
break;
case ESC : done = YES;
break;
default : for (i = 0; i <= mcount; i++)
if ( mstr[i] == (char) ch )
done = YES;
break;
}
} while ( done == NO );
// close the file
d_fileclose(d_infile);
rval[0] = (char) ch;
rval[1] = '\0';
}
#ifdef CLIPPER5
_xfree(d_buffer);
_xfree(d_lbuff);
#endif
// return key value to Clipper
_retc(rval);
}